#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<assert.h>

#define LEFT "["
#define RIGHT "]"
#define LABLE "#"
#define DELIM " \t"
#define LINE_SIZE 1024
#define ARGV_SIZE 32

extern char** environ;
char commandline[LINE_SIZE];
char* argv[ARGV_SIZE];
char pwd[LINE_SIZE];
char myenv[LINE_SIZE];

int lastcode=0;
int quit=0;

const char* getuser()
{
    return getenv("USER");
}

const char* gethostname()
{
    return getenv("HOSTNAME");
}

void getpwd()
{
    getcwd(pwd,sizeof(pwd));
}

void interact(char* cline,int size)
{
    getpwd();
    printf(LEFT"%s@%s %s"RIGHT""LABLE" ",getuser(),gethostname(),pwd);
    char* s=fgets(cline,size,stdin);
    assert(s);
    (void)s;
    cline[strlen(cline)-1]='\0';

    //printf("echo : %s",cline);
}

int splitstring(char cline[],char* _argv[])
{
    int i=0;
    _argv[i++]=strtok(cline,DELIM);
    while(_argv[i++]=strtok(NULL,DELIM));

    return i-1;
}

void normalexcute(char* _argv[])
{
    pid_t id=fork();
    if(id<0)
    {
        perror("fork");
        //continue;
        return ;
    }
    else if(id==0)
    {
        //子进程执行指令
        //execvpe(argv[0],argv,environ);
        execvp(argv[0],argv);
    }
    else{
        int status=0;
        pid_t rid=waitpid(id,&status,0);
        if(rid==id)
        {
            lastcode=WEXITSTATUS(status);
        }
    }
}

int buildcommand(char* _argv[],int _argc)
{
    if(_argc==2&&strcmp(_argv[0],"cd")==0)
    {
        chdir(_argv[1]);
        getpwd();
        sprintf(getenv("PWD"),"%s",pwd);
        return 1;
    }
    else if(_argc==2&&strcmp(_argv[0],"export")==0)
    {
        strcpy(myenv,_argv[1]);
        putenv(myenv);
        return 1;
    }
    else if(_argc==2&&strcmp(_argv[0],"echo")==0)
    {
        if(strcmp(_argv[1],"$?")==0)
        {
            printf("%d\n",lastcode);
            lastcode=0;
        }
        else if(*_argv[1]=='$')
        {
            char* s=getenv(_argv[1]+1);
            if(s) printf("%s\n",s);
        }
        else{
            printf("%s\n",_argv[1]);
        }

        return 1;

    }

    //特殊处理ls
    if(_argc==2&&strcmp(_argv[0],"ls")==0)
    {
        _argv[_argc++]="--color";
        _argv[_argc]=NULL;
    }

    return 0;

}

int main()
{
    while(!quit)
    {
        //交互问题，获得命令行参数
        interact(commandline,sizeof commandline);

        //字符串分割，解析命令行参数
        int argc = splitstring(commandline,argv);
        if(argc==0) continue;

        //指令的判断
        int n=buildcommand(argv,argc);        

        //普通指令的执行
        if(!n)normalexcute(argv);
    }
        return 0;
}

